; ELEC254 LCD INTERFACING DEMO PROGRAM SEPT 24, 2002 VERSION 1.1 

; ----- PORT DEFINATION -----
RS      EQU     P3.2                ; RS Pin
RW      EQU     P3.3                ; RW Pin
EN      EQU     P3.4                ; Enable Pin
OUTPUT  EQU     P2                ; Output Port

; ----- RAM DEFINATION -----
STARTUP EQU     20H
CNT     EQU     30H
OFFSET  EQU     31H
CURPOS  EQU     32H
KEYIN   EQU     33H


; ----- PROGRAM START -----
        ORG     00H
        LJMP    MAIN
        ORG     23H
        LJMP    SERIAL

MAIN:
        MOV     SP, #5FH
        ; ------- Please insert your Serial Initialization Code here
;-------------------
        MOV SCON, #50H
        MOV PCON, #00H
        MOV TMOD, #20H
        MOV TH1, #0FDH
        SETB TR1
        MOV IE, #90H

        MOV R0, #0

        ; ------- The End of your Serial Initialization Code   -------------------

        LCALL   INIT                    ; Subroutine for LCD INITIZATION
        LCALL   SHOW_STARTUP                ; Subroutine for Showing Startup Message
        LJMP    $

; ----- INITIZATION LCD -----
INIT:
        MOV     A, #00111000B           ; SET FUNCTION 8 BIT 2 LINE 5*8
        LCALL   W_INS
        MOV     A, #00111000B           ; SET FUNCTION 8 BIT 2 LINE 5*8
        LCALL   W_INS
        MOV     A, #00111000B           ; SET FUNCTION 8 BIT 2 LINE 5*8
        LCALL   W_INS
        MOV     A, #00111000B           ; SET FUNCTION 8 BIT 2 LINE 5*8
        LCALL   W_INS
        MOV     A, #00001000B           ; DISPLAY OFF
        LCALL   W_INS
        MOV     A, #00000001B           ; CLEAR DISPLAY
        LCALL   W_INS
        MOV     A, #00000110B           ; SET ENTRY MODE
        LCALL   W_INS
        MOV     A, #00001111B           ; DISPLAY ON, CURSOR ON, BLINKING
        LCALL   W_INS
        RET
; ----------------------------

; ------ W_INS : This Procedure will send the instruction to LCD
;---------------------
W_INS:
        LCALL   CHECK
        CLR     EN
        CLR     RS
        CLR     RW
        SETB    EN
        MOV     OUTPUT, A
        CLR     EN
        RET
;
;------------------------------------------------------------------------------------


; ----- SHOW STARTUP IMAGE -----
SHOW_STARTUP:
        SETB    STARTUP
        MOV     A, #10000000B           ; SET CURSOR POSITION 00H, LINE 1,POS 1
        LCALL   W_INS
        MOV     CNT, #16
        MOV     DPTR, #MSG0
        LCALL   W_STR
        MOV     A, #11000000B           ; SET CURSOR POSITION 40H, LINE 2,POS 2
        LCALL   W_INS
        MOV     CNT, #16
        MOV     DPTR, #MSG1
        LCALL   W_STR
        RET
; ------------------------------


; ------ W_STR : This Procedure will output the 16 Characters to the LCD
;------------
W_STR:
        MOV     OFFSET, #0
NEXT:
        MOV     A, OFFSET
        MOVC    A, @A+DPTR
        LCALL   W_DATA
        INC     OFFSET
        DJNZ    CNT, NEXT
        RET
;
;------------------------------------------------------------------------------------


; ------ W_DATA : This Procedure will send the data to LCD
;---------------------
W_DATA:
        LCALL   CHECK
        CLR     EN
        SETB    RS
        CLR     RW
        SETB    EN
        MOV     OUTPUT, A
        CLR     EN
        RET
;
;------------------------------------------------------------------------------------


; ------ CHECK : This Procedure will CHECK if LCD is BUSY 
;---------------------
CHECK:
        PUSH    ACC
BUSY:
        CLR     RS
        SETB    RW
        SETB    EN
        MOV     OUTPUT, #11111111B
        MOV     A, OUTPUT
        CLR     EN
        JB      ACC.7, BUSY
        POP     ACC
        RET
;
;------------------------------------------------------------------------------------


; **************** INTERRRUPT SERIAL START HERE
;********************************
; **************** Please insert your code here
;********************************

SERIAL:
        JNB TI, INT_RI
        CLR TI
        RETI
INT_RI:
        MOV A, R0
        JNZ N_CLR_SCREEN
        MOV A, #01H
        LCALL W_INS
N_CLR_SCREEN:
        MOV A, SBUF
        ANL A, #07FH
        MOV R1, A

        ADD A, #0F8H
        JZ BS
        MOV A, R1
        ADD A, #0F3H
        JZ ENTER
        MOV A, R1
        ADD A, #0E5H
        JZ ESC

CHAR:
        MOV A, R0
        XRL A, #50H
        JNZ N_LN2_END
        MOV R0, #00H
        MOV A, #80H
        LCALL W_INS
        MOV A, #01H
        LCALL W_INS
        MOV A, R1
        LCALL W_DATA
        INC R0
        CLR RI
        RETI

N_LN2_END:
        MOV A, R1
        LCALL W_DATA

        MOV A, R0
        XRL A, #0FH
        JNZ SAME_LN
        MOV R0, #40H
        MOV A, #0C0H
        LCALL W_INS
        CLR RI
        RETI

SAME_LN:
        INC R0
        CLR RI
        RETI

BS:
        MOV A, R0
        XRL A, #40H
        JNZ NOT_LN2
        MOV R0, #10H
        MOV A, #10H
        ORL A, #80H
        LCALL W_INS
NOT_LN2:
        MOV A, R0
        XRL A, #00H
        JZ NO_BS

CLR_SAME_LN:
        MOV A, R0
        ADD A, #0FFH
        ORL A, #80H
        LCALL W_INS
        MOV A, #20H
        LCALL W_DATA

        MOV A, R0
        ADD A, #0FFH
        MOV R0, A
        ORL A, #80H
        LCALL W_INS


NO_BS:        CLR RI
        RETI

ENTER:
        MOV A, R0
        ANL A, #0F0H
        XRL A, #00H
        JNZ LN_2
        MOV R0, #40H
        MOV A, #0C0H
        LCALL W_INS
        CLR RI
        RETI

LN_2:
        MOV R0, #00H
        MOV A, #80H
        LCALL W_INS
        MOV A, #01H
        LCALL W_INS
        CLR RI
        RETI

ESC:
        MOV R0, #00H
        LCALL SHOW_STARTUP
        CLR RI
        RETI

;
;*******************************************************************************

MSG0:   DB      '  ELEC3300 LAB5  '
MSG1:   DB      ' LCD INTERFACING'
NULL:   DB      '                '
        END
